#include "StdAfx.h"
#include "CrashDumper.h"

#include <dbghelp.h>

#pragma comment (lib, "dbghelp.lib")

CCrashDumper::CCrashDumper(void)
{
}

CCrashDumper::~CCrashDumper(void)
{
}


void CCrashDumper::Install()
{
	SetUnhandledExceptionFilter(DumpCrashData);
}

LONG WINAPI CCrashDumper::DumpCrashData(EXCEPTION_POINTERS *lpExceptionInfo)
{
	LONG ret = EXCEPTION_EXECUTE_HANDLER;

	TCHAR szFileName[MAX_PATH] = {0};
	SYSTEMTIME st;
	::GetLocalTime(&st);
	if(GetModuleFileName(NULL, szFileName, ARRAY_SIZE(szFileName)))
	{			
		TCHAR drive[_MAX_DRIVE];
		TCHAR dir[_MAX_DIR];
		TCHAR fname[_MAX_FNAME];
		_tsplitpath( szFileName, drive, dir, fname, NULL);
		_sntprintf(szFileName, ARRAY_SIZE(szFileName)-1, _T("%s%s%s_%04d%02d%02d-%02d%02d%02d-%03d.dmp"), drive,dir, fname, st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond, st.wMilliseconds);
	}
	else
	{
		_sntprintf(szFileName, ARRAY_SIZE(szFileName)-1, _T("crash_%04d%02d%02d-%02d%02d%02d-%03d.dmp"), st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond, st.wMilliseconds);
	}

	HANDLE hFile = ::CreateFile(szFileName, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL );
	if (hFile != INVALID_HANDLE_VALUE)
	{
		MINIDUMP_EXCEPTION_INFORMATION ExInfo;

		ExInfo.ThreadId = ::GetCurrentThreadId();
		ExInfo.ExceptionPointers = lpExceptionInfo;
		ExInfo.ClientPointers = FALSE;

		MiniDumpWriteDump(GetCurrentProcess(), GetCurrentProcessId(), hFile, MiniDumpNormal, &ExInfo, NULL, NULL );
		::CloseHandle(hFile);
	}

	return ret;
}
